/**
 * Created by artheru on 2016/12/20.
 */

//import 'babel-polyfill';
import io from 'socket.io-client';

const chatURL="http://chat.huan68.com:4590/message"

let message={
    addMessageHandler,
    conversations:{},
    conversationOrder:[],
    clearConversationUnread,
    pullConversation,
    sendMessage,
    listConversations,
    init,
    totalUnread: 0,
};

let socket;
let uid;


let messageHandlers=[];
function addMessageHandler(handler){
    messageHandlers.push(handler);
}

function listConversations() {
    return new Promise((res, rej) =>
        socket.emit("listConversations", "", (items) => {
            for (let item of items) {
                if (message.conversationOrder.indexOf(item.otherParty) != -1)
                    continue;
                message.conversationOrder.push(item.otherParty);
                message.totalUnread += parseInt(item.unread);
                message.conversations[item.otherParty] = item;
            }
            console.log("listed conversations.");
            res();
        })
    );
}

function pullConversation(otherParty) {
    return new Promise((res, rej) => {
        let conv = message.conversations[otherParty];
        let fromMid;
        if (!conv) {
            message.conversations[otherParty] = {messages:[]};
            conv = message.conversations[otherParty];
        }else
            fromMid=conv.messages[conv.messages.length-1].mid;
        socket.emit("pullConversation", {otherParty, fromMid}, (messages) => {
            conv.messages = conv.messages.concat(messages);
            console.log("pulled conversation.");
            res(messages);
        });
    });
}

function clearConversationUnread(otherParty){
    return new Promise((res,rej)=> {
        if (!message.conversations[otherParty]){
            console.log("no need to clear");
            res(); return;
        }
        message.totalUnread -= message.conversations[otherParty].unread;
        message.conversations[otherParty].unread = 0;
        socket.emit("clearUnread", otherParty);
        console.log("cleared.");
        res();
    });
}

function recordMessage(msg){
    let otherParty=uid==msg.from?msg.to:msg.from;
    if (!message.conversations[otherParty])
        message.conversations[otherParty]={unread:1, messages:[]};
    let conversation=message.conversations[otherParty];
    conversation.messages.push(msg);
    conversation.unread += 1;
    message.totalUnread += 1;
    let idx = message.conversationOrder.indexOf(otherParty);
    if (idx >= 0)
        message.conversationOrder.splice(idx, 1);
    message.conversationOrder.unshift(otherParty);
}

function sendMessage(to, messageType, messageContent){
    return new Promise(function(res,rej){
        socket.emit("send", {to,messageType,messageContent}, (back)=>{
            if (back.mid>0) {
                let msg={from:uid, to, messageType, messageContent, mid:back.mid};
                recordMessage(msg);
                res(msg);
            }
            else
                rej("bad mid");
        })
    });
}

function init(token) {
    return new Promise((res,rej)=> {
        socket = io(chatURL);
        socket.on("failure", (e) => {
            console.log(e)
            rej(e);
        });
        socket.on("message", (msg) => {
            recordMessage(msg);
            for (let handler of messageHandlers)
                handler(msg);
        });
        socket.on("tokenified", (_uid) => {
            uid = _uid
        });
        socket.on("connect", () =>
            socket.emit("authentication", token, () => {
                console.log("IM connection ready");
                res();
            })
        );
    });
}

if (!window.message)
    window.message=message;
export default message;